package edu.hawaii.solardecathlon.page;

import java.util.Map;
import org.apache.wicket.ResourceReference;
import org.apache.wicket.markup.html.CSSPackageResource;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.markup.html.link.Link;
import edu.hawaii.solardecathlon.SolarDecathlonApplicationSession;
import edu.hawaii.solardecathlon.page.admin.AdminPage;
import edu.hawaii.solardecathlon.page.aquapond.FishPage;
import edu.hawaii.solardecathlon.page.cooling.CoolingPage;
import edu.hawaii.solardecathlon.page.energy.EnergyPage;
import edu.hawaii.solardecathlon.page.help.HelpPage;
import edu.hawaii.solardecathlon.page.home.HomePage;
import edu.hawaii.solardecathlon.page.images.BaseSet;
import edu.hawaii.solardecathlon.page.images.IconSet;
import edu.hawaii.solardecathlon.page.light.LightingPage;
import edu.hawaii.solardecathlon.page.media.MediaPage;
import edu.hawaii.solardecathlon.page.security.SecurityPage;
import edu.hawaii.solardecathlon.page.style.IEStylesheetHeaderContributor;
import edu.hawaii.solardecathlon.page.voice.VoicePage;
import edu.hawaii.solardecathlon.page.water.WaterPage;

/**
 * A Base page that serves as the superclass for all pages in this application. All pages inherit
 * from this class. This class also adds the CSS stylesheets that will be used by all pages.
 * 
 * @author Harry Kwan
 * @author Solar Decathlon Group 7
 * @author Philip Johnson
 */
public abstract class BasePage extends WebPage {

  /** Support serialization. */
  private static final long serialVersionUID = 1L;
  protected static final String header = "header";
  protected static final String description = "description";
  protected static final String style = "style";
  protected Map<String, String> props = getSessionProperties();
  /**
   * The base page layout used by all pages. This includes a title and the links that appear in the
   * tabbed menu.
   */
  public BasePage() {
    BaseSet baseLogos = new BaseSet();
    IconSet icons = new IconSet();
    
    // Add CSS definitions for use in all pages
    add(CSSPackageResource.getHeaderContribution(edu.hawaii.solardecathlon.page.BasePage.class,
        "style/blueprint/screen.css", "screen"));
    add(CSSPackageResource.getHeaderContribution(edu.hawaii.solardecathlon.page.BasePage.class,
        "style/blueprint/print.css", "print"));
    add(new IEStylesheetHeaderContributor(new ResourceReference(
        edu.hawaii.solardecathlon.page.BasePage.class, "style/blueprint/ie.css")));

    // Add logos, header and description
    add(new Label("title", "Solar Decathlon TeamHawaii"));
    add(new Image("sd_logo", baseLogos.sdLogo));
    add(new Label("header", props.get("header")));
    add(new Label("description", props.get("description")).setEscapeModelStrings(false));
    add(new Image("teamhawaii_logo", baseLogos.teamLogo));

    // Now add the links that go in the tabs.
    add(new Link<String>("HomePageLink") {
      private static final long serialVersionUID = 1L;

      /** Upon clicking this link, go to HomePage. */
      @Override
      public void onClick() {
        putProperty(header, "Home");
        putProperty(description, "Solar Decathlon Home Managment System.<br/>"
            + "Login for more advanced options.");
        setResponsePage(new HomePage());
      }
    }
    .add(new Image("home", icons.home)));
    add(new Link<String>("EnergyPageLink") {
      private static final long serialVersionUID = 1L;

      /** Upon clicking this link, go to EnergyPage. */
      @Override
      public void onClick() {
        putProperty(header, "Energy");
        putProperty(description, "View energy usage per object and monitor energy levels.");
        setResponsePage(new EnergyPage());
      }
    }
    .add(new Image("energy", icons.energy)));
    add(new Link<String>("LightingPageLink") {
      private static final long serialVersionUID = 1L;

      /** Upon clicking this link, go to LightingPage. */
      @Override
      public void onClick() {
        putProperty(header, "Lighting");
        putProperty(description, "Configure behaviors of lights throughout your home.");
        setResponsePage(new LightingPage());
      }
    }
    .add(new Image("light", icons.light)));
    add(new Link<String>("CoolingPageLink") {
      private static final long serialVersionUID = 1L;

      /** Upon clicking this link, go to CoolingPage. */
      @Override
      public void onClick() {
        putProperty(header, "Cooling");
        putProperty(description, "Configure the HVAC system used to cool and warm up rooms.");
        setResponsePage(new CoolingPage());
      }
    }
    .add(new Image("cooling", icons.cooling)));
    add(new Link<String>("WaterPageLink") {
      private static final long serialVersionUID = 1L;

      /** Upon clicking this link, go to WaterPage. */
      @Override
      public void onClick() {
        putProperty(header, "WaterHeater");
        putProperty(description,
            "View statistics about your water heater usage.<br/>Make a schedule to save money.");
        setResponsePage(new WaterPage());
      }
    }
    .add(new Image("water", icons.water)));
    add(new Link<String>("AquaponicsPageLink") {
      private static final long serialVersionUID = 1L;

      /** Upon clicking this link, go to AquaponicsPage. */
      @Override
      public void onClick() {
        putProperty(header, "Aquaponics");
        putProperty(description, "Monitors pH level and temperature of Aquaponics system.");
        setResponsePage(new FishPage());
      }
    }
    .add(new Image("aqua", icons.aqua)));
    add(new Link<String>("MediaPageLink") {
      private static final long serialVersionUID = 1L;

      /** Upon clicking this link, go to MediaPage. */
      @Override
      public void onClick() {
        putProperty(header, "Media");
        putProperty(description, "Configure various media aspects built into your home.");
        setResponsePage(new MediaPage());
      }
    }
    .add(new Image("media", icons.media)));
    add(new Link<String>("VoicePageLink") {
      private static final long serialVersionUID = 1L;

      /** Upon clicking this link, go to VoicePage. */
      @Override
      public void onClick() {
        putProperty(header, "Voice");
        putProperty(description,
            "Configure the built-in microphone and voice recognition settings.");
        setResponsePage(new VoicePage());
      }
    }
    .add(new Image("voice", icons.voice)));
    add(new Link<String>("SecurityPageLink") {
      private static final long serialVersionUID = 1L;

      /** Upon clicking this link, go to SecurityPage. */
      @Override
      public void onClick() {
        putProperty(header, "Security");
        putProperty(description, "Manage security settings of your home.");
        setResponsePage(new SecurityPage());
      }
    }
    .add(new Image("security", icons.security)));
    add(new Link<String>("AdminPageLink") {
      private static final long serialVersionUID = 1L;

      /** Upon clicking this link, go to AdminPage. */
      @Override
      public void onClick() {
        putProperty(header, "Admin");
        putProperty(description, "Configure user logins, services and non-admin permission.");
        setResponsePage(new AdminPage());
      }
    }
    .add(new Image("admin", icons.admin)));
    add(new Link<String>("HelpPageLink") {
      private static final long serialVersionUID = 1L;

      /** Upon clicking this link, go to HelpPage. */
      @Override
      public void onClick() {
        putProperty(header, "Help");
        putProperty(description, "Explanation of your Home Management System.");
        setResponsePage(new HelpPage());
      }
    }
    .add(new Image("help", icons.help)));
  }

  /**
   * Get current session object.
   * 
   * @return SolarDecathlonApplicationSession Current session.
   */
  private SolarDecathlonApplicationSession getSolarDecathlonApplicationSession() {
    return ((SolarDecathlonApplicationSession) getSession());
  }

  /**
   * Store page header and description in session properties.
   * 
   * @param header Page header.
   * @param description Page description.
   */
  protected void putProperty(String header, String description) {
    getSolarDecathlonApplicationSession().setProperties(header, description);
  }

  /**
   * Returns the property map associated with this user's session.
   * 
   * @return The session's property map.
   */
  public Map<String, String> getSessionProperties() {
    return getSolarDecathlonApplicationSession().getProperties();
  }

  /**
   * Get page specific properties.
   * 
   * @param type Desired page properties.
   * @return Properties of page.
   */
  public Map<String, String> getSessionProperties(String type) {
    return getSolarDecathlonApplicationSession().getProperties(type);
  }
}
